package com.zzyl.serve.service.impl;


import java.util.Collections;
import java.util.List;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.*;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.exception.base.BaseException;

import com.zzyl.common.utils.StringUtils;
import com.zzyl.serve.dto.DeviceDto;
import com.zzyl.serve.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.serve.mapper.DeviceMapper;
import com.zzyl.serve.domain.Device;
import com.zzyl.serve.service.IDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 设备Service业务层处理
 * 
 * @author chenbw
 * @date 2025-08-22
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService
{
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private IoTDAClient iotdAClient;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 查询设备列表
     *
     * @param device 设备
     * @return 设备
     */
    @Override
    public List<Device> selectDeviceList(Device device)
    {
        return deviceMapper.selectDeviceList(device);
    }

    @Override
    public void syncProductList() {
        //1.从物联网平台查询所有产品列表
        ListProductsRequest request = new ListProductsRequest();
        ListProductsResponse response = iotdAClient.listProducts(request);
        if(response.getHttpStatusCode() != 200){
            throw new BaseException("物联网接口-同步设备列表失败");
        }

        //2.将产品列表缓存到Redis中
        redisTemplate.opsForValue()
                .set(CacheConstants.IOT_PRODUCT_LIST_KEY, JSONUtil.toJsonStr(response.getProducts()));
    }

    @Override
    public List<ProductVo> allProduct() {
        //1.从Redis中查询产品列表
        String str = (String) redisTemplate.opsForValue().get(CacheConstants.IOT_PRODUCT_LIST_KEY);
        //2.查不到返回空
        if(StringUtils.isEmpty(str)){
            return Collections.emptyList();
        }
        //3.将Redis中的json数组转换成ProductVo列表并返回
        return JSONUtil.toList(str,ProductVo.class);
    }

    /**
     * 注册设备
     * @param deviceDto
     */
    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //判断设备名称是否重复
        LambdaQueryWrapper<Device> wrapper = Wrappers.<Device>lambdaQuery()
                .eq(Device::getDeviceName, deviceDto.getDeviceName());
        if(count(wrapper) > 0){
            throw new BaseException("设备名称已存在，请重新输入");
        }
        //检验设备标识码是否重复
        wrapper = new LambdaQueryWrapper<Device>()
                .eq(Device::getNodeId, deviceDto.getNodeId());
        if(count(wrapper) > 0){
            throw new BaseException("设备标识码已存在，请重新输入");
        }

        //校验同一位置是否绑定了同一类产品
        wrapper = Wrappers.<Device>lambdaQuery()
                .eq(Device::getProductKey, deviceDto.getProductKey())
                .eq(Device::getLocationType, deviceDto.getLocationType())
                .eq(Device::getPhysicalLocationType, deviceDto.getPhysicalLocationType())
                .eq(Device::getBindingLocation, deviceDto.getBindingLocation());
        if (count(wrapper) > 0) {
            throw new BaseException("该老人/位置已绑定该产品，请重新选择");
        }

        //iot中新增设备
        AddDeviceRequest request = new AddDeviceRequest();
        AddDevice body = new AddDevice();
        body.withProductId(deviceDto.getProductKey());
        body.withDeviceName(deviceDto.getDeviceName());
        body.withNodeId(deviceDto.getNodeId());

        AuthInfo authInfo = new AuthInfo();
        //秘钥：利用Hutool工具包的UUID类生成
        String secret = UUID.randomUUID().toString(true);
        authInfo.withSecret(secret);
        body.setAuthInfo(authInfo);
        request.setBody(body);
        AddDeviceResponse response = iotdAClient.addDevice(request);

        //设备数据保存到数据库
        //属性拷贝
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        //设备id、设备绑定状态
        device.setIotId(response.getDeviceId());
        //秘钥
        device.setSecret(secret);

        //在数据库中新增设备
        save(device);
    }


}
